#!/bin/bash

# Check parameters
if [ -z "$1" ]
then
    echo "Usage: `basename $0` EBSU_DIR [map/info/suggest]"
    exit 1
fi

if [ ! -d "$1" ]
then
    echo "`basename $0`: \"$1\" is not a directory, while it should be".
    exit 1
fi

EFI_DIR=`find $1 -name efi -type d 2>/dev/null | head -n 1`
if [ $? -ne 0 ] || [ -z "$EFI_DIR" ]
then
    echo "`basename $0`: Can not find 'efi' directory, quit!"
    exit 1
fi

if [ -z "$2" ]
then
    PRINT="map"
else
    case "$2" in 
    "map")
        PRINT="map";;
    "info")
        PRINT="info";;
    "suggest")
        PRINT="suggest";;
    *)
        echo "`basename $0`: Can not understand print params, quit!"
        exit 1;;
    esac
fi


SPU=$EFI_DIR/configutils/cfg/spu.ini
PCI=$EFI_DIR/configutils/cfg/PciTable.ini
SEPERATOR=";"
TMP1="./tmp1.lst"
TMP2="./tmp2.lst"
rm -rf $TMP2 $TMP2

# Make temp list containing firmware version
cat $SPU | awk -F '=' 'BEGIN{ \
    is_first_line = 1; \
    print_this_key = 0; \
    seperator="'"$SEPERATOR"'"; \
    supp_cards=""; \
}{\
    if ( $1 ~ /^\[.*\]$/ ) { \
        is_nic_card = 0;
        gsub( /\[|\]|" "/, "", $1 ); \
        lowname=tolower($1); \
        if ( lowname ~ /^platforms|^version/ ) {\
            print_this_key = 0 \
        } else if ( lowname ~ /^rx.+|^bl.+|^hpvm|^sanddune/ ) {\
            if ( lowname ~ /.+_sys$|.+SYS$/ ) { \
                print_this_key = 1 \
            } else { \
                print_this_key = 0 \
            } \
        } else { \
            print_this_key = 1 ;\
        }\
        if ( print_this_key ) {\
            if ( is_first_line ) { \
                printf("%s%s" ,$1, seperator); \
                is_first_line = 0 \
            } else { \
                printf("\n%s%s" ,$1, seperator) \
            } \
            if (supp_cards != "") { \
                printf("%s%s", supp_cards, seperator ) \
            } \
            supp_cards = ""; \
        }\
    }\
    if ( $1 ~ /^component_1|^component_2|^component_3/ ) { printf("FWV::%s%s", $2, seperator) }\
    if ( $1 ~ /^group_[0-9]+/ ) { \
        if ( supp_cards == "" ) { supp_cards = sprintf("SUP::%s", $2) } \
        else                    { supp_cards = sprintf("%s,%s", supp_cards, $2) }\
    } \
}END{\
    printf("\n")\
}' > $TMP1

# Link the name with pcitable
let cnt=1;
cat $TMP1 | awk -F ';' 'BEGIN{ pcitbkey = "" }{ \
    pcitbkey = ""; \
    for ( i=1; i<NF; i++ ) \
        if ( $i ~ /^FWV::.+/ ) { \
            split( $i, arr, "," ); \
            gsub( /^FWV::/, "", arr[1]); \
            pcitbkey = arr[1]; \
            break \
        }\
    if ( pcitbkey != "" ) print pcitbkey; \
}' | while read pcitbkey
do
    head -n $cnt $TMP1 | tail -n 1 | awk -F ';' '{ for (i=1; i<NF; i++) { printf("%s;", $i) } }'  >> $TMP2
    let cnt=cnt+1
    cat $PCI | awk -F '=' 'BEGIN{ key="'"$pcitbkey"'"; item_start=0; seperator="'"$SEPERATOR"'" }{\
        if ( $1 ~ /^\[.*\]$/ ) {\
            if ( item_start == 1 ) exit 0; \
            if ( $1 ~ key ) item_start=1 ; \
        }\
        if ( item_start ) {\
            if ( $1 ~ /^DESCRIPTION/ ) printf("DES::%s%s", $2, seperator );\
            if ( ! ( key ~ /^sfw.*/ ) ) {\
                if ( $1 ~ /^VENDOR/ ) printf("PCI::V-%s,", $2 );\
                if ( $1 ~ /^DEVICE/ ) printf("D-%s,", $2 );\
                if ( $1 ~ /^SUBVENDOR/ ) printf("SV-%s,", $2 );\
                if ( $1 ~ /^SUBDEVICE_[0-9+]/ ) printf("SD-%s,", $2 );\
                if ( $1 ~ /^COUNT/ ) printf("%s", seperator );\
                if ( $1 ~ /^FORCE_DVD_DRIVER/ ) printf("DVD::%s%s", $2, seperator );\
            }\
        }\
    }END{ printf("\n") }' >> $TMP2
done

# Print support matrix
cat $TMP2 | awk -F ';' 'BEGIN{\
    seperator="'"$SEPERATOR"'"; \
    srv_crd["srv", "card"]="1"; \
    cmp_fwv["cmp"]="fwv"; \
    cmp_des["cmp"]="des"; \
    cmp_pci["cmp"]="pci"; \
    cmp_dvd["cmp"]="dvd"; \
    idx_srv = 0; \
    idx_crd = 0; \
}{\
    sup_str = ""; \
    fwv_str = ""; \
    des_str = ""; \
    pci_str = ""; \
    dvd_str = ""; \
    comp_name = $1; \
    gsub ( /_SYS$/, "", comp_name ); \
    for ( i=1; i<NF; i++ ){\
       if ( $i ~ /^SUP::.+/ ) sup_str = substr( $i, 6 ); \
       if ( $i ~ /^FWV::.+/ ) {\
           split( substr( $i, 6 ), arr_tmp, "," ); \
           if (arr_tmp[1] ~ /^sfw.*/) { arr_tmp[1]="sfw" }\
           else if (arr_tmp[1] ~ /^bmc.*/) { arr_tmp[1]="bmc" }\
           else if (arr_tmp[1] ~ /^gsp.*/) { arr_tmp[1]="gsp" }\
           else if (arr_tmp[1] ~ /.+drv$/) { arr_tmp[1]="drv" }\
           else { arr_tmp[1]="fw " }\
           fwv_str = sprintf( "%s%-4s%-12s", fwv_str, arr_tmp[1], arr_tmp[2] ); 
       }\
       if ( $i ~ /^DES::.+/ ) des_str = substr( $i, 6 ); \
       if ( $i ~ /^PCI::.+/ ) {\
           pci_str = substr( $i, 6 ); \
           gsub( /SV-/, "SV=", pci_str ); \
           gsub( /SD-/, "SD=", pci_str ); \
           gsub( /V-/, "VD=", pci_str ); \
           gsub( /D-/, "DV=", pci_str ); \
       }
       if ( $i ~ /^DVD::.+/ ) {\
           dvd_str = sprintf( "Force DVD driver = %s", substr( $i, 6 ) ); \
       }
    }\
    if ( sup_str != "" ) {\
        idx_srv = idx_srv + 1; \
        srv_lst[idx_srv] = comp_name; \
        split( sup_str, arr_tmp, "," ); \
        for ( i in arr_tmp ){\
            srv_crd[ comp_name, arr_tmp[i] ] = "";\
        }\
    }else{\
        idx_crd = idx_crd + 1; \
        crd_lst[idx_crd] = comp_name;\
    }\
    if ( fwv_str != "" ) cmp_fwv [comp_name] = fwv_str;\
    if ( des_str != "" ) cmp_des [comp_name] = des_str;\
    if ( pci_str != "" ) cmp_pci [comp_name] = pci_str;\
    if ( dvd_str != "" ) cmp_dvd [comp_name] = dvd_str;\
}END{\
    sepln="---------------";\
    for ( i=1; i<=idx_srv; i++ ) sepln = sprintf( "%s-------", sepln ); \
    if ( "'"$PRINT"'" == "map" ) {\
        printf("\n");\
        printf("                           EBSU Support Matrix\n");\
        printf("\n");\
        printf("%s\nCOMPONENT_NAME|", sepln); \
        for ( i=1; i<=idx_srv; i++ ) {\
            printf("%-6s|", toupper( substr( srv_lst[i], 1, 6 ) ) );\
        }\
        printf("\n%s\n", sepln);\
        for ( j=1; j<=idx_crd; j++ ){\
            printf("%14s|", substr(crd_lst[j], 1, 12) );\
            for ( i=1; i<=idx_srv; i++ ) {\
                supported = "      "; \
                cmb = sprintf("%s%s%s", srv_lst[i], SUBSEP, crd_lst[j] ); \
                if ( cmb in srv_crd ) supported = " Yes  "; \
                printf("%-6s|", supported );\
            }\
            printf("\n");\
        }\
        printf("%s\n\n\n", sepln);\
    }\
    \
    if ( "'"$PRINT"'" == "info" ) {\
        printf("\n");\
        printf("                        EBSU Hardware Information\n");\
        printf("%s\n", sepln);\
        for ( i=1; i<=idx_srv; i++ ) {\
            if ( srv_lst[i] in cmp_fwv ) printf("    - %-15s%s\n", srv_lst[i], cmp_fwv[srv_lst[i]] );\
        }\
        printf("%s\n", sepln);\
        for ( j=1; j<=idx_crd; j++ ) {\
            name = sprintf( "%s%s", crd_lst[j], sepln );\
            name = substr( name, 1, 14 ); \
            gsub( /---$/, "+--", name ); \
            if ( crd_lst[j] in cmp_des ) printf("    - %-15s %s\n", name, cmp_des[crd_lst[j]] );\
            if ( crd_lst[j] in cmp_pci ) printf("                 |    %s\n", cmp_pci[crd_lst[j]] );\
            if ( crd_lst[j] in cmp_dvd ) printf("                 |    %s\n", cmp_dvd[crd_lst[j]] );\
            if ( crd_lst[j] in cmp_fwv ) printf("                 \\--  %s\n", cmp_fwv[crd_lst[j]] );\
        }\
        printf("%s\n\n\n", sepln);\
    }\
    \
    if ( "'"$PRINT"'" == "suggest" ) {\
        printf("\n");\
        printf("                       EBSU Modification Advisor\n");\
        printf("\n");\
        printf("    - EBSU supproted servers = %-3d;\n", idx_srv);\
        printf("    - EBSU supproted cards   = %-3d;\n", idx_crd);\
        printf("    - Those cards exist in EBSU SPU without any support( by platform ):\n");\
        printf("      [ ");\
        for ( j=1; j<=idx_crd; j++ ){\
            is_supported = 0; \
            for ( i=1; i<=idx_srv; i++ ) {\
                cmb = sprintf("%s%s%s", srv_lst[i], SUBSEP, crd_lst[j] ); \
                if ( cmb in srv_crd ) { is_supported = 1; break } \
            }\
            if ( ! is_supported ) { printf("%s, ", crd_lst[j] )} \
        }\
        printf("];\n");\
        printf("    - Those components exist in EBSU pcitable are not linked to SPU :\n");\
        printf("      [ ");\
    }\
}'

# Get pcitable component that not listed in spu file
if [ "$PRINT" == "suggest" ]
then
    cat $PCI | awk -F '=' '{\
        if ( $1 ~ /^\[.*\]$/ ) {\
            name = $1;\
            gsub( /\[|\]|" "/, "", name ); \
            if ( !( name ~ /SUPPORT/ ) ){\
                print name;\
            }\
        }\
    }' | while read ckname
    do
        cat $SPU | awk -F '=' 'BEGIN{ ckname = "'"$ckname"'"; found = 0 }{\
            if ( $1 ~ /^component_[0-9]+/ ) {\
                split( $2, arr_tmp, "," ) ;\
                name = arr_tmp[1];\
                if ( name == ckname ) found = 1; \
            }\
        }END{ if ( !found ) printf("%s, ", ckname ) }'
    done
    echo -e "];\n\n\n"
fi

rm -f $TMP1 $TMP2
